home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
201-225
/
disk_217
/
stevie
/
amiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
9KB
|
434 lines
/*
* Amiga system-dependent routines.
*/
#include <proto/exec.h>
#include <proto/dos.h>
#include <exec/memory.h>
#include <devices/conunit.h>
#include <stdio.h>
#include <ios1.h>
#include <error.h>
#include "stevie.h"
/* Globals initialized by get_ConUnit() */
struct Window *conWindow;
struct ConUnit *conUnit;
extern int errno; /* The error variable */
long raw_in = 0;
long raw_out = 0;
#define BSIZE 2048
static char outbuf[BSIZE];
static int bpos = 0;
void
flushbuf()
{
if (bpos != 0)
Write(raw_out, outbuf, bpos);
bpos = 0;
}
void
outchar(c)
char c;
{
outbuf[bpos++] = c;
if (bpos >= BSIZE)
flushbuf();
}
void
outstr(s)
char *s;
{
while (*s) {
outbuf[bpos++] = *s++;
if (bpos >= BSIZE)
flushbuf();
}
}
int
GetCharacter()
{
char c;
Read(raw_in, &c, sizeof(c));
return ((int) c);
}
/*
* getCSIsequence - get a CSI sequence
* - either cursor keys, help, or function keys
*/
int
getCSIsequence()
{
int c;
int tmp;
c = GetCharacter();
if (isdigit(c)) {
tmp = 0;
while (isdigit(c)) {
tmp = tmp * 10 + c - '0';
c = GetCharacter();
}
if (c == '~') /* function key */
return ((char) (K_F1 + tmp));
}
switch (c) {
case 'A': /* cursor up */
return K_UARROW;
case 'B': /* cursor down */
return K_DARROW;
case 'C': /* cursor right */
return K_RARROW;
case 'D': /* cursor left */
return K_LARROW;
case 'T': /* shift cursor up */
return K_SUARROW;
case 'S': /* shift cursor down */
return K_SDARROW;
case ' ': /* shift cursor left or right */
c = GetCharacter();
if (c == 'A') /* shift cursor left */
return K_SLARROW;
if (c == '@') /* shift cursor right */
return K_SRARROW;
break;
case '?': /* help */
c = GetCharacter();
if (c == '~')
return K_HELP;
break;
}
while ((c != '|') && (c != '~')) {
if (WaitForChar(raw_in, 500L) == 0)
break;
c = GetCharacter();
}
/* must have been screen resize event */
s_clear();
flushbuf();
if (get_ConUnit(raw_in) != 0) { /* hopefully never exit .... */
emsg("STEVIE: can't get ConUnit info ?!?!?!?\n");
sleep(5);
return 0;
}
Rows = conUnit->cu_YMax + 1;
Columns = conUnit->cu_XMax + 1;
if (Columns < 5)
Columns = 5;
if (Columns > MAX_COLUMNS)
Columns = MAX_COLUMNS;
if (Rows < 2)
Rows = 2;
P(P_LI) = Rows;
screenalloc();
tmp = RedrawingDisabled;
RedrawingDisabled = TRUE;
S_NOT_VALID;
cursupdate(UPDATE_ALL); /* make sure not below Botchar */
RedrawingDisabled = FALSE;
s_refresh(NOT_VALID); /* draw it */
RedrawingDisabled = tmp;
windgoto(Cursrow, Curscol);
flushbuf();
return 0;
}
/*
* inchar() - get a character from the keyboard
*/
int
inchar()
{
int c;
flushbuf();
for (;;) {
c = GetCharacter();
if (c == 0x9b)
c = getCSIsequence();
if (c != 0)
break;
}
return c;
}
void
beep()
{
if (RedrawingDisabled)
return;
outbuf[bpos++] = '\007';
if (bpos >= BSIZE)
flushbuf();
}
void
sleep(n)
int n;
{
void Delay();
if (n > 0)
Delay(50L * n);
}
void
delay()
{
void Delay();
Delay(25L);
}
void
windinit()
{
raw_in = Input();
if (!IsInteractive(raw_in)) {
raw_in = Open("RAW:0/0/480/200/STEVIE", MODE_NEWFILE);
if (raw_in == NULL) {
fprintf(stderr, "STEVIE: Can't open window ?!?!?!?\n");
exit(2);
}
raw_out = raw_in;
} else {
raw_out = Output();
if (raw(raw_in) != 0) {
perror("STEVIE: Can't change to raw mode ?!?!?!?");
exit(2);
}
}
if (get_ConUnit(raw_in) != 0) {
fprintf(stderr, "STEVIE: can't get ConUnit info ?!?!?!?\n");
windexit(3);
}
/* get window size */
P(P_LI) = Rows = conUnit->cu_YMax + 1;
Columns = conUnit->cu_XMax + 1;
outstr("\033[12{"); /* window resize events activated */
flushbuf();
}
void
windexit(r)
int r;
{
outstr("\033[12}"); /* window resize events de-activated */
flushbuf();
if (raw_in != raw_out) {
if (cooked(raw_in) != 0)
perror("STEVIE: Can't change to cooked mode ?!?!?!?");
} else {
Close(raw_in);
}
exit(r);
}
void
windgoto(r, c)
int c;
int r;
{
r++;
c++;
outstr("\033[");
if (r >= 10)
outchar((char) (r / 10 + '0'));
outchar((char) (r % 10 + '0'));
outchar(';');
if (c >= 10)
outchar((char) (c / 10 + '0'));
outchar((char) (c % 10 + '0'));
outchar('H');
}
FILE *
fopenb(fname, mode)
char *fname;
char *mode;
{
FILE *fopen();
char modestr[16];
sprintf(modestr, "%sb", mode);
return fopen(fname, modestr);
}
/*
* raw() & cooked()
*
* These are routines for setting a given stream to raw or cooked mode on the
* Amiga. This is useful when you are using Lattice C to produce programs
* that want to read single characters with the "getch()" or "fgetc" call.
*
* Written : 18-Jun-87 By Chuck McManis.
*/
/*
* Function raw() - Convert the specified File Handle to 'raw' mode. This
* only works on TTY's and essentially keeps DOS from translating keys for
* you.
*/
long
raw(afh)
struct FileHandle *afh;
{
struct MsgPort *mp; /* The File Handle message port */
long Arg[1], res;
mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
Arg[0] = -1L;
res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
if (res == 0) {
errno = ENXIO;
return (-1);
}
return (0);
}
/*
* Function - cooked() this function returns the designate file pointer to
* it's normal, wait for a <CR> mode. This is exactly like raw() except that
* it sends a 0 to the console to make it back into a CON: from a RAW:
*/
long
cooked(afh)
struct FileHandle *afh;
{
struct MsgPort *mp; /* The File Handle message port */
long Arg[1], res;
mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
Arg[0] = 0L;
res = SendPacket(mp, ACTION_SCREEN_MODE, Arg, 1);
if (res == 0) {
errno = ENXIO;
return (-1);
}
return (0);
}
/*
* Code for this routine came from the following :
*
* ConPackets.c - C. Scheppner, A. Finkel, P. Lindsay CBM
* DOS packet example
* Requires 1.2
*
* which I found on Fish Disk 56.
*/
/* initializes conWindow and conUnit (global vars) */
long
get_ConUnit(afh)
struct FileHandle *afh;
{
struct MsgPort *mp; /* The File Handle message port */
struct InfoData *id;
long Arg[8], res;
if (!IsInteractive((BPTR) afh)) {
errno = ENOTTY;
return (-1);
}
mp = ((struct FileHandle *) (BADDR(afh)))->fh_Type;
/* Alloc to insure longword alignment */
id = (struct InfoData *) AllocMem(sizeof(struct InfoData),
MEMF_PUBLIC | MEMF_CLEAR);
if (!id) {
errno = ENOMEM;
return (-1);
}
Arg[0] = ((ULONG) id) >> 2;
res = SendPacket(mp, ACTION_DISK_INFO, Arg, 1);
conWindow = (struct Window *) id->id_VolumeNode;
conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
FreeMem(id, sizeof(struct InfoData));
if (res == 0) {
errno = ENXIO;
return (-1);
}
return (0);
}
/*
* SendPacket() - written by Phil Lindsay, Carolyn Scheppner, and Andy
* Finkel. This function will send a packet of the given type to the Message
* Port supplied.
*/
long
SendPacket(pid, action, args, nargs)
struct MsgPort *pid; /* process indentifier ... (handlers message
* port ) */
long action, /* packet type ... (what you want handler to
* do ) */
args[], /* a pointer to a argument list */
nargs; /* number of arguments in list */
{
struct MsgPort *replyport;
struct StandardPacket *packet;
long count, *pargs, res1;
replyport = (struct MsgPort *) CreatePort(NULL, 0);
if (!replyport)
return (0);
/* Allocate space for a packet, make it public and clear it */
packet = (struct StandardPacket *)
AllocMem((long) sizeof(struct StandardPacket),
MEMF_PUBLIC | MEMF_CLEAR);
if (!packet) {
DeletePort(replyport);
return (0);
}
packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
packet->sp_Pkt.dp_Port = replyport;
packet->sp_Pkt.dp_Type = action;
/* copy the args into the packet */
pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
for (count = 0; count < nargs; count++)
pargs[count] = args[count];
PutMsg(pid, packet); /* send packet */
WaitPort(replyport);
GetMsg(replyport);
res1 = packet->sp_Pkt.dp_Res1;
FreeMem(packet, (long) sizeof(struct StandardPacket));
DeletePort(replyport);
return (res1);
}